home *** CD-ROM | disk | FTP | other *** search
/ Amiga Mag HDD Backup / Amiga Mag HDD Backup.zip / Amiga Mag HDD Backup / Alexander.img.bin / Alexander.img / ***9.11 All NEWer important / texts / Do Not Use-Barrett⁄MusicX-Arexx / MusicX-Magic.txt < prev    next >
Text File  |  1983-05-04  |  25KB  |  641 lines

  1.                               Music-X Magic:
  2.                      Soup Up Your Sequencer With ARexx
  3.  
  4.                     Copyright 1994 by Daniel J. Barrett
  5.  
  6.  
  7.     After a several year wait between updates, Music-X 2.0 finally
  8. arrived last Spring.  One of the significant changes is that the program
  9. now supports ARexx, the Amiga's inter-program communication language.  This
  10. is very good news:  you can now extend Music-X's capabilities in powerful
  11. ways by writing "scripts" that operate on your sequences. For example,
  12. scripts can count the number of musical events in a sequence, transpose
  13. your music in various ways, or perform algorithmic composition.  You can
  14. even make Music-X communicate with other ARexx compatible programs (more
  15. than 400 exist) to increase your power even further.  For example, you can
  16. send data from Music-X directly into Deluxe Music 2.0 for musical notation,
  17. or communicate with a statistical package to analyze your sequences.
  18.  
  19.     Unfortunately, the ARexx documentation for Music-X is very sketchy.
  20. The manual is brief, omits some vital facts, and the example scripts
  21. mentioned in the manual (page 22) were omitted from the program. This
  22. article clarifies the manual, reveals the missing information, and teaches
  23. you how to write several useful scripts.  This article assumes that you
  24. have at least looked at the ARexx chapter of the upgrade manual; keep it
  25. nearby for reference.
  26.  
  27.  
  28. A MOTIVATING EXAMPLE
  29.  
  30.     Let's begin with a simple script that transposes all the notes in
  31. your sequence upward by a perfect fifth (7 semitones).  The numbers 1-12 on
  32. the left side are not part of the script; they are for our reference only.
  33.  
  34.     1    /* Transpose up by a perfect fifth. */
  35.     2    OPTIONS RESULTS
  36.     3    BeginScan ALL
  37.     4    NextEvent
  38.     5    DO WHILE RESULT = 1
  39.     6        IF Event.Type = "NOTE" THEN DO
  40.     7            Event.Num = Event.Num + 7
  41.     8            ReplEvent
  42.     9        END
  43.     10        NextEvent
  44.     11    END
  45.     12    EndScan
  46.  
  47. Let's examine what each line means.
  48.  
  49.     1.    A comment.  Every ARexx script must begin with a comment;
  50.         this is required, or else the script will not work.
  51.     2.    Tell ARexx to report the results of certain commands in
  52.         a variable called "RESULT".  We need this variable on
  53.         line 5.
  54.     3.    Tell Music-X that we want to examine (scan through) all
  55.         the events in the current sequence.
  56.     4.    Read the first event.  Its data is automatically stored in
  57.         a special variable called "Event".
  58.     5-11.    This "loop" is the heart of the script.  As each event is
  59.         read, its type is checked.  If it is a NOTE event, add 7 to
  60.         its note number, and use "ReplEvent" to make the change
  61.         permanent.  No matter what, we move to the next event and
  62.         repeat.  When there are no more events, "NextEvent" will
  63.         fail, RESULT will equal zero (meaning failure), and the
  64.         loop ends.
  65.     12.    Tell Music-X we are done scanning the sequence.
  66.  
  67.     Type this script into a file called "Transposer.mxe".  Now load
  68. a sequence into the Bar Editor, choose "Rexx..." from the Modules menu,
  69. use the file requestor to locate your Transposer.mxe script, and double-click
  70. on the script name.  Voila!  Your notes have been transposed.
  71.  
  72.  
  73. BASIC CONCEPTS
  74.     
  75.     ARexx support in Music-X is handled by a new module called
  76. RexxEdit.  This module is automatically installed when you use the Music-X
  77. installation program.  However, due to a bug in the installation, all your
  78. modules may not be accessible due to incorrect path names.  If you
  79. encounter this, then exit Music-X, run the "Install Modules" program, click
  80. on each module name and remove the leading colon ":" from its Path, choose
  81. "Save", and restart Music-X.
  82.  
  83.     In a nutshell, RexxEdit allows you to do four kinds of operations:
  84.  
  85.     1. Examine, add, delete, and change data in sequences.
  86.     2. Display requestors with a variety of gadgets for user input.
  87.     3. Get information about the bar editor:  grid size,
  88.        selected regions, step size, etc.
  89.     4. Communicate with other ARexx-compatible programs.
  90.  
  91. In addition, RexxEdit does NOT allow you to:
  92.  
  93.     1. Control recording and playback.
  94.     2. Control the Tool List in the Bar and Event Editors.
  95.     3. Use the cut, copy, and paste features.
  96.     4. Display or hide events in the Bar and Event Editors.
  97.     5. Affect the controls on the Sequencer, Filters, Samples, and
  98.        Librarian pages.
  99.  
  100. Perhaps a later version of Music-X will support such operations; but given
  101. how long it took for the 2.0 update, I have my doubts.
  102.  
  103.  
  104. OPERATIONS ON SEQUENCES
  105.  
  106.     Scripts that operate on sequences typically look a lot like
  107. our "Transposer.mxe" example.  First, BeginScan must be called to examine
  108. the sequence. This is followed by a loop which examines each event using
  109. NextEvent and processes it in some way.  When NextEvent returns "0" in the
  110. RESULT variable, the loop is finished, and we call EndScan.
  111.  
  112.     If you plan to add events to a sequence using AddEvent, there is
  113. an undocumented step which you MUST do:  initialize the "Event" variable. 
  114. This is done by placing the line
  115.  
  116.                Event. = ""
  117.  
  118. once in your script, before any call to AddEvent.  Note that the
  119. period after "Event" is mandatory because it is a stem variable.  It
  120. doesn't matter what value you assign here; for example,
  121.  
  122.             Event. = 192873
  123.  
  124. will work equally well.
  125.  
  126.     As an example, let's modify Transposer.mxe so instead of moving
  127. the notes, it adds new notes 7 semitones above the originals.  For
  128. example, every C will get a new G added above it.  This requires two
  129. changes:  initialize the "Event" variable (say, between lines 2 and 3),
  130. and change the ReplEvent on line 8 to AddEvent.  Store the script in a new
  131. file called Interval.mxe and test it out.
  132.  
  133.  
  134. REQUESTORS AND USER INPUT
  135.  
  136.     Our Transposer.mxe script is useful but limited. What if you want
  137. to transpose notes by sevenths instead of fifths? Do we need a whole new
  138. script for every kind of transposition?  Nope!  In this section, we will
  139. add a requestor to Transposer.mxe with several gadgets, allowing user
  140. control over the script's behavior.
  141.  
  142.     RexxEdit can display three kinds of requestors: a file requestor
  143. (MXFile), a "tell the user" requestor (MXReport), and a gadget-filled
  144. requestor for user input (MXRequest).  The first two are well explained on
  145. page 46 of the upgrade manual.  Our example will use the more complicated
  146. MXRequest.  There are four steps to using it:
  147.  
  148.     1. Decide whether you want a 1-column or 2-column requestor,
  149.        using the MXColumn command.  (Optional.)
  150.  
  151.     2. Define your gadgets.  Your choices are:
  152.  
  153.         MXButton    On/Off buttons.
  154.         MXSlider    Sliders with positive values.
  155.         MXMirror    Sliders with negative and positive values.
  156.         MXString    String gadgets for text input.
  157.         MXNoteSize    The Music-X note duration control.
  158.         MXLabel        Plain text; not for user input.
  159.  
  160.     3. Display the requestor with the MXRequest command.
  161.  
  162.     4. Read the gadgets with the MXValue command to find out the user's
  163.        selections.
  164.  
  165.     Our example lets the user choose a transposition interval, whether
  166. to replace or add notes, and whether to affect all notes or just
  167. selected/marked notes.  First, let's design the requestor.
  168.  
  169.     1    /* A requestor for transposing. */
  170.     2    OPTIONS RESULTS
  171.     3    MXMirror "Semitones:,127"
  172.     4    MXRadio "Replace existing notes,Add new notes"
  173.     5    MXRadio "All notes,Selected notes only"
  174.     6    MXRequest "My Transposer"
  175.  
  176. Lines 3-5 define three gadgets:  a "Semitones" slider running from -127 to
  177. +127, a pair of buttons for choosing replace or add, and another pair of
  178. buttons for choosing all or selected notes.  Line 6 actually displays the
  179. requestor with our gadgets, as shown in Figure 1.  To display it yourself,
  180. save lines 1-5 in a script called "Requestor.mxe" and execute it.  Play
  181. around with the gadgets all you like, but remember that this requestor will
  182. have no actual effect on your sequence... yet.
  183.  
  184.     Continuing, let's find out what the user chose to do.  If the
  185. user clicked CANCEL, the RESULT variable will have value 0.  If so,
  186. we choose to exit immediately:
  187.  
  188.     7    IF RESULT = 0 THEN
  189.     8        EXIT
  190.  
  191.     Next, we check our three defined gadgets using MXValue. To read the
  192. first gadget, use "MXValue 1"; for the second, "MXValue 2"; etc. The gadget
  193. value is returned in the RESULT variable.  For "Semitones" slider, we store
  194. the results in a variable "semitones":
  195.  
  196.     9    MXValue 1
  197.     10    semitones = RESULT
  198.  
  199. The "add/replace" radio buttons have value 0 if the first button was
  200. chosen, or a 1 for the second button:
  201.  
  202.     11    MXValue 2
  203.     12    add = RESULT
  204.  
  205. For the "all/selected events" buttons, we set the variable "scanType" to
  206. "ALL" or "SELECTED" appropriately.  These words have special value for
  207. the BeginScan command later:
  208.  
  209.     13    MXValue 3
  210.     14    IF RESULT = 0 THEN
  211.     15        scanType = "ALL"
  212.     16    ELSE
  213.     17        scanType = "SELECTED"
  214.  
  215. Save lines 1-17 in a file called "Requestor2.mxe", execute it, play with
  216. the gadgets, and see what happens.
  217.  
  218.     Now we are done with gadgets and user input, so it's time to do
  219. the actual transposition.
  220.  
  221.     18    Event. = ""
  222.     19    BeginScan scanType
  223.     20    NextEvent
  224.     21    DO WHILE RESULT = 1
  225.     22        IF Event.Type = "NOTE" THEN DO
  226.     23            Event.Num = Event.Num + semitones
  227.     24            IF add = 1 THEN
  228.     25                AddEvent
  229.     26            ELSE
  230.     27                ReplEvent
  231.     28        END
  232.     29        NextEvent
  233.     30    END
  234.  
  235.     Note how similar this is to the loop in Transposer.mxe.  The only
  236. differences are in lines:
  237.  
  238.     18.    Initialize the Event variable so we can add events.
  239.     19.    BeginScan is instructed to scan ALL or SELECTED events,
  240.         based on the user choice.
  241.     23.    We now add the value "semitones" instead of 7.
  242.     24-27.    Depending on the user's choice, we either add or replace
  243.         the notes we transpose.
  244.  
  245.     Put lines 1-30 in a file called NewTransposer.mxe, and have fun
  246. with this highly useful script!  If you try to transpose notes higher than
  247. MIDI allows (127), Music-X will "wrap then around" to 0 again; similarly
  248. for note numbers below 0.  A note of caution:  this script has very little
  249. error checking.  You really should check the value of RESULT after the
  250. BeginScan, AddEvent, and ReplEvent commands to make sure they worked.
  251.  
  252.  
  253. EXAMINING THE BAR EDITOR
  254.  
  255.     In this section, we will build a script for adding pitch bend to a
  256. marked or selected region.  Pitch bend events will be added, one at a time,
  257. at regular intervals in the region.  The user may define how far apart
  258. the pitch bend events are. When followed by Music-X's Sculpt tool, this
  259. script will let you create interesting pitch-bend shapes.
  260.  
  261.     Bar Editor information is examined by using the GetBarData command.
  262. This command fills in the variable "BarData" with information like the
  263. current grid size, measure size, beginning and end of a marked region, etc.
  264. GetBarData is used like this:
  265.  
  266.     1    /* Bar Data example with pitch bend events. */
  267.     2    OPTIONS RESULTS
  268.     3    GetBarData
  269.     4    IF RESULT = 0 THEN DO
  270.     5        MXReport "Could not get bar data."
  271.     6        EXIT
  272.     7    END
  273.  
  274. Next, we detect whether there is a region defined.
  275.  
  276.     8    IF BarData.Select = "NONE" THEN DO
  277.     9        MXReport "No region is marked/selected."
  278.     10        EXIT
  279.     11    END
  280.  
  281.     Save lines 1-11 to a file called "CheckRegion.mxe" and execute it.
  282. If no region is marked or selected, the script will display the MXReport
  283. requestor.
  284.  
  285.     Next, we allow the user to choose the spacing between the pitch
  286. bend events, using an MXNoteSize gadget, and the MIDI channel for the
  287. events, using a slider gadget.  We store the user's choices in the
  288. variables "spacing" and "midiChannel", respectively.
  289.  
  290.     12    MXNoteSize "Set Spacing:"
  291.     13    MXSlider "MIDI Channel:,1,16,1"
  292.     14    MXRequest "Add Pitch Bend Events"
  293.     15    IF RESULT = 0 THEN
  294.     16        EXIT
  295.     17    MXValue 1
  296.     18    spacing = RESULT
  297.     19    MXValue 2
  298.     20    midiChannel = RESULT - 1
  299.  
  300. The reason for "RESULT - 1" is that Music-X stores MIDI channels 1-16
  301. as 0-15 internally.  Add lines 12-20 to your script so you can see the
  302. requestor in Figure 2.
  303.  
  304.     Next, we locate the beginning and end of the region.  Time in
  305. Music-X is measured in bars (measures) and clocks (clock ticks in each
  306. measure).  For example, a note might appear in bar 17, clock 2475. 
  307. Information about bars and clocks is stored in the variables:
  308.  
  309.     BarData.Start.Bars    Measure number of the start of the region.
  310.     BarData.Start.Clocks    Clock number of the start of the region.
  311.     BarData.Stop.Bars    Measure number of the end of the region.
  312.     BarData.Stop.Clocks    Clock number of the end of the region.
  313.     BarData.Measure        Number of clocks per measure.
  314.  
  315.     We use our own variable "currentTime" to represent the current
  316. location in the region as we add events.  As the script progresses, we
  317. repeatedly add a number of clocks (stored in the "spacing" variable) to the
  318. current time.  However, when adding an event, we need to know the Bars and
  319. Clocks values, which will require a little math.
  320.  
  321.     Given the measure number and clock number of a Music-X event, the
  322. formula for calculating its location in clocks is:
  323.  
  324.         (Measure number) * (Clocks per Measure) + (Clock number)
  325.  
  326. Thus, in our script, we compute the starting and ending times of our
  327. region, in clocks:
  328.  
  329.     21    currentTime = BarData.Start.Bars * BarData.Measure    ,
  330.                   + BarData.Start.Clocks
  331.     22    endTime        = BarData.Stop.Bars  * BarData.Measure    ,
  332.                   + BarData.Stop.Clocks
  333.  
  334. (Note:  In ARexx, a comma means "continued on the next line."  If you can
  335. fit each command on one line -- not possible on this magazine page -- then
  336. you must omit the commas.)
  337.  
  338.     Next, we prepare to scan the region.  Just for fun, while the
  339. script is working, we change the pointer to the "sleeping cloud" to
  340. indicate work is being done.
  341.  
  342.     23    MXPointer "SLEEPY"
  343.     24    Event. = ""        /* Initialize Event variable */
  344.     25    BeginScan
  345.  
  346.     Since we are adding pitch bend events, we can fill in some of
  347. the Event variable fields that will remain constant:  the event type,
  348. the MIDI channel, and an event value (we choose +8192, which is zero
  349. pitch bend).
  350.  
  351.     26    Event.Type    = "PBEN"
  352.     27    Event.Channel    = midiChannel
  353.     28    Event.Num    = 8192
  354.  
  355.     Finally, it is time to add pitch bend events!  To add them at the
  356. right locations, we must calculate the Bar and Clock numbers where they
  357. should be added.  The bar number is obtained using integer division (the
  358. "%" operator), and the clock number using the "mod" or "remainder" function
  359. (the "//" operator):
  360.  
  361.     29    DO WHILE currentTime <= endTime
  362.     30        Event.Start.Bars   = currentTime %  BarData.Measure
  363.     31        Event.Start.Clocks = currentTime // BarData.Measure
  364.     32        AddEvent
  365.     33        currentTime        = currentTime + spacing
  366.     34    END
  367.  
  368. When the loop is done, clean up and exit.
  369.  
  370.     35    EndScan
  371.     36    MXPointer "NORMAL"
  372.  
  373.     Save lines 1-36 in a file called "PitchBend.mxe". To use this
  374. script, first mark a region or select some events.  Second, run the
  375. PitchBend.mxe script.  Third, use the Sculpt Tool to shape the pitch bend
  376. events the way you want them. Enjoy!
  377.  
  378.     Note:  RexxEdit has a bug concerning marked regions.  If a region
  379. appears to be marked, but you keep getting the requestor "No region is
  380. marked/selected," try marking the region again or using the Select tool
  381. instead of Mark.  (See "TECH TALK" below for more information.)
  382.  
  383.     Another note:  the above assumes you are using "relative time"
  384. sequences, not "absolute time" sequences.  If you use absolute time
  385. sequences, then time is measured in quarter frames instead of clocks;
  386. see the manual for more information.
  387.  
  388.  
  389. COMMUNICATING WITH OTHER PROGRAMS
  390.  
  391.     Using the ARexx "ADDRESS" command, Music-X scripts can talk to
  392. other ARexx-compatible products such as Deluxe Music 2.0, Bars and Pipes
  393. Professional, One Stop Music Shop, and even non-music products.  How about
  394. using SuperBase Professional to store your Music-X sequences?  VLT for
  395. uploading and downloading sequences?  AmigaVision for multimedia?  The
  396. possibilities are numerous and exciting.
  397.  
  398.     Communicating with another program has 4 steps.
  399.  
  400.     1. Find out the ARexx port names of the other program, by
  401.        consulting its documentation.
  402.  
  403.     2. Store Music-X's port name in a variable for safekeeping,
  404.        using the Address() command.  (See "TECH TALK", below,
  405.        if you are interested in the reason.)
  406.  
  407.     3. Use the Show("P") command to make sure that the other programs
  408.        are running.  If not, then your script run them, using the
  409.        "WaitForPort" command to wait until the program is running.
  410.  
  411.     4. Use the "ADDRESS" command to talk to the other programs.
  412.  
  413.     In this section, we write scripts to communicate with Electronic
  414. Arts' Deluxe Music 2.0 notation program, port name "DMUSIC", and Oxxi's
  415. TurboText editor, port name "TURBOTEXT".  Our first script sends the
  416. currently selected Music-X note to Deluxe Music, inserting it at Deluxe
  417. Music's current cursor location.
  418.  
  419.     First, we save Music-X's port name in a variable "myAddress":
  420.  
  421.     1    /* Example script using Deluxe Music 2.0. */
  422.     2    OPTIONS RESULTS
  423.     3    myAddress = Address()
  424.  
  425. Next, we make sure that something is selected.
  426.  
  427.     4    GetBarData
  428.     5    IF BarData.Select ~= "SELECT" THEN DO
  429.     6        MXReport "Nothing is selected."
  430.     7        EXIT
  431.     8    END
  432.  
  433. Next, we make sure that the selected event is a note.
  434.  
  435.     9    BeginScan "SELECTED"
  436.     10    NextEvent
  437.     11    EndScan
  438.     12    IF Event.Type ~= "NOTE" THEN DO
  439.     13        MXReport "You must select a note."
  440.     14        EXIT
  441.     15    END
  442.  
  443.     Next, we make sure Deluxe Music is running by looking for its
  444. ARexx port.  If a port named "DMUSIC" does not exist, then we run
  445. Deluxe Music.
  446.  
  447.     16    IF ~Show('P', 'DMUSIC') THEN DO
  448.     17        ADDRESS COMMAND 
  449.     18        "Run < NIL: > NIL: DMusic"
  450.     19        WaitForPort "DMUSIC"
  451.     20    END
  452.  
  453. Now, we are ready to send the note from Music-X to Deluxe Music.
  454.  
  455.     21    ADDRESS "DMUSIC" 
  456.     22    INSERTITEM NOTE PITCH Event.Num
  457.     23    NEXT NOTE
  458.  
  459.     Finally, we pop the Deluxe Music screen to the front to see our
  460. handiwork:
  461.  
  462.     24    SCREENTOFRONT
  463.  
  464.     Save lines 1-24 to a file called "DMusic.mxe", execute the script,
  465. and watch what happens.  With some work, this script could be the basis for
  466. a whole direct interface between Music-X and Deluxe Music. You may notice
  467. that we didn't use the myAddress variable.  This is because the script did
  468. all its Music-X communication first, and then all its Deluxe Music
  469. communication.
  470.  
  471.     The next example is more complex, sending information about notes
  472. and their velocities from a sequence into a TurboText edit window.  We
  473. start off with the usual, saving Music-X's address and invoking TurboText
  474. if it is not running:
  475.  
  476.     1    /* Send note information to TurboText. */
  477.     2    OPTIONS RESULTS
  478.     3    myAddress = Address()
  479.     4    IF ~Show("P", "TURBOTEXT") THEN DO
  480.     5        ADDRESS COMMAND
  481.     6        "TTX > NIL: BACKGROUND NOWINDOW"
  482.     7        WaitForPort "TURBOTEXT"
  483.     8    END
  484.  
  485.     Next, we tell TurboText to open a new edit window.  The name of
  486. that window (its own ARexx port) is returned in the RESULT variable:
  487.  
  488.     9    ADDRESS "TURBOTEXT"
  489.     10    OpenDoc
  490.     11    windowName = RESULT
  491.  
  492.     Finally, we talk to Music-X again, scan through the sequence,
  493. picking out notes, and sending their information to the TurboText window:
  494.  
  495.     12    ADDRESS VALUE myAddress
  496.     13    BeginScan ALL
  497.     14    NextEvent
  498.     15    DO WHILE RESULT = 1
  499.     16        IF Event.Type = "NOTE" THEN DO
  500.     17            ADDRESS VALUE windowName
  501.     18            Insert "Note" Event.Num "Vel" Event.Attack
  502.     19            InsertLine
  503.     20            ADDRESS VALUE myAddress
  504.     21        END
  505.     22        NextEvent
  506.     23    END
  507.     24    EndScan
  508.  
  509.     I realize that these Deluxe Music and TurboText scripts are harder
  510. to understand than the previous ones.  This is because each program has its
  511. own set of commands, such as "OpenDoc" and "Insert" in the TurboText example.
  512. Writing scripts that connect two programs means learning the command sets for
  513. both programs, and this may require careful reading of each program's
  514. documentation, as well as a lot of hair pulling!
  515.  
  516.  
  517. REXXEDIT TIPS AND TRICKS
  518.  
  519.     Here is a set of (mostly undocumented) tips and tricks I've
  520. discovered while writing Music-X scripts.
  521.  
  522. o    The MXReport command is great for helping to debug your scripts.
  523.     If you want to see the value of a variable (say, "myVar") at any
  524.     time, just insert the line "MXReport myVar" at the appropriate spot
  525.     in the script.  If you need more space for messages, use MXLabel
  526.     and MXRequest.
  527.  
  528. o    If your gadgets in an MXRequest don't have enough space between
  529.     them for your tastes, the command
  530.  
  531.         MXLabel ""
  532.  
  533.     will insert a blank line.  Remember to count this MXLabel
  534.     command when using MXValue to read gadget values!
  535.  
  536. o    By default, the RexxEdit module is available only inside the Bar
  537.     and Event Editors.  But you can use the "Install Modules" script
  538.     to make it available in other pages.  Simply click on the
  539.     other checkboxes in the "Install Modules" window, quit and
  540.     restart Music-X, and you're set.  The ARexx functionality will
  541.     be more limited on other pages, because there is no "current
  542.     sequence" being displayed, but you can still do some interesting
  543.     things.
  544.  
  545. o    The "Event" variable has different fields depending on what
  546.     type of event it contains.  For example, a NOTE event has its
  547.     velocity in Event.Attack, but it does not use Event.Pressure.
  548.     You must write your scripts carefully so they examine ONLY
  549.     the Event fields that apply to the current event.  Read pages
  550.     49-52 carefully to learn which event fields are valid.
  551.     (See also the next item.)
  552.  
  553. o    The spacing and boldfacing on pages 49 and 50 of the Music-X 2.0
  554.     Upgrade Manual is messed up, making it difficult to distinguish
  555.     event types from variables.  Four variable names are incorrectly
  556.     boldfaced:  EVENT.DEM belongs to the TSIG event, EVENT.TRANSPOSE
  557.     and EVENT.CUT belong to the PSEQ event, and EVENT.ATTACK belongs
  558.     to the NOTE event.
  559.  
  560. o    The range of pitch bend values goes from -8192 to +8191, with
  561.     0 being zero pitch bend.  PBEN event values
  562.     (Event.Num) are really between 0 and 16383; that
  563.     is, 8192 higher than the actual bend value.  If you use an MXMirror
  564.     gadget to get pitch bend values from the user, remember to
  565.     add 8192 to the result before storing it in Event.Num.
  566.  
  567. o    Since pitch bend goes from -8192 to +8191, not +8192.  If you use an
  568.     MXMirror slider for pitch bend, the highest positive value +8192
  569.     is invalid.  So your script may need code like this:
  570.  
  571.         MXValue 3          /* Get the MXMirror value. */
  572.         value = RESULT
  573.         IF value = 8192 THEN      /* Disallow +8192 value.   */
  574.             value = 8191
  575.  
  576.  
  577. REXXEDIT PROBLEMS
  578.  
  579.     One of RexxEdit's omissions is that it has no ARexx command for
  580. disabling user input.  While a script is running, all gadgets on the Music-X
  581. screen are "live," even though they do not appear to respond, and they will
  582. react to all of your inadvertent keystrokes and mouseclicks when the script
  583. finishes.  So, while a script is executing, don't click on any gadgets
  584. except those in an ARexx requestor (e.g., MXRequest).  As a visual aid, do
  585. "MXPointer SLEEPY" while a script is running.
  586.  
  587.     Second, RexxEdit cannot abort a script in progress.  Suppose your
  588. script scans a sequence with a loop, but you forget to call NextEvent in
  589. it.  You now have an infinite loop and no way to stop it except by
  590. rebooting your Amiga.
  591.  
  592.     Third, as mentioned earlier, Music-X "forgets" any marked region
  593. every time RexxEdit is run.  This is especially confusing because the
  594. region on the screen still appears to be marked.  The problem does not
  595. occur with selected events. To get around this problem, either use
  596. selecting instead of marking when possible, or re-mark the region after
  597. each ARexx macro is run.  There is also a problem with the selected
  598. events.  The Select tool works fine.  However, if you use the Move or Add
  599. tools and click on an event, it highlights as if it were selected.  Other
  600. modules like the Quantizer will treat it as selected.  However, RexxEdit
  601. does not think it is selected.  The moral:  if a script requires selected
  602. events, you must use the Select tool.
  603.  
  604.  
  605. TECH TALK
  606.  
  607.     If you've used ARexx before, you may notice that Music-X's
  608. interface is unusual in several notable ways.  First, its ARexx port name
  609. is completely undocumented.  By using the command
  610.  
  611.         MXReport Address()
  612.  
  613. I discovered that the name is "MUSIC-X AREXX EDIT". However, this
  614. information is of no use, because of a second non-standard feature:  it's
  615. impossible to control Music-X from another program.  All scripts must be
  616. run from inside Music-X.  This is because the ARexx port belongs to
  617. RexxEdit, not to Music-X. When RexxEdit is not running, the port
  618. disappears, and when RexxEdit is running, Music-X occupies its full
  619. attention.
  620.  
  621.     A third oddity involves ARexx return codes.  By convention, ARexx
  622. commands return their success (1) or failure (0) values in the "RC"
  623. variable.  Music-X uses the "RESULT" variable instead, which is usually
  624. reserved for more complex return values.  RC is unused.  Until you figure
  625. this out, you'll be scratching your head wondering why your error-checking
  626. doesn't work.
  627.  
  628.  
  629. GOOD LUCK!
  630.  
  631.     By using ARexx and RexxEdit, you can personalize Music-X with
  632. powerful new tools of your own invention.  It takes some effort to get
  633. used to ARexx, but the results can really be worth it.
  634.  
  635. ===
  636.  
  637. Daniel J. Barrett has been working in electronic and computer music since
  638. 1979, and an Amiga owner since 1987.  He is currently pursuing a Ph.D. in
  639. computer science at the University of Massachusetts.  He welcomes
  640. electronic mail at his Internet address, barrett@cs.umass.edu.
  641.